package com.ruoyi.app.business.score;

import com.ruoyi.app.business.message.MessageBusiness;
import com.ruoyi.app.config.util.UserUtil;
import com.ruoyi.app.domain.score.CompanyScore;
import com.ruoyi.app.domain.score.LaborScore;
import com.ruoyi.common.core.utils.CommonUtils;
import com.ruoyi.service.company.service.CompanyService;
import com.ruoyi.service.message.enums.MessageTemplateEnum;
import com.ruoyi.service.project.entity.ProjectEntity;
import com.ruoyi.service.project.enums.ProjectStatusEnum;
import com.ruoyi.service.project.service.ProjectLaborService;
import com.ruoyi.service.project.service.ProjectService;
import com.ruoyi.service.score.entity.CompanyScoreDetailEntity;
import com.ruoyi.service.score.entity.CompanyScoreEntity;
import com.ruoyi.service.score.entity.LaborScoreDetailEntity;
import com.ruoyi.service.score.entity.LaborScoreEntity;
import com.ruoyi.service.score.service.CompanyScoreDetailService;
import com.ruoyi.service.score.service.CompanyScoreService;
import com.ruoyi.service.score.service.LaborScoreDetailService;
import com.ruoyi.service.score.service.LaborScoreService;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import org.springframework.stereotype.Component;
import org.springframework.transaction.support.TransactionTemplate;

/**
 * <p>
 * 作用：评价管理器
 * </p>
 *
 * @author Zane
 * @since 2025-10-22 20:50
 */
@Component
public class ScoreBusiness {

  @Resource
  private ProjectService projectService;

  @Resource
  private CompanyScoreService companyScoreService;
  @Resource
  private CompanyScoreDetailService companyScoreDetailService;
  @Resource
  private LaborScoreService laborScoreService;
  @Resource
  private LaborScoreDetailService laborScoreDetailService;
  @Resource
  private ProjectLaborService projectLaborService;
  @Resource
  private CompanyService companyService;
  @Resource
  private MessageBusiness messageBusiness;

  @Resource
  private TransactionTemplate transactionTemplate;

  public void companyRate(CompanyScore companyScore) {
    final ProjectEntity project = getAndCheckProject(companyScore.getProjectId());
    //是否已经对该项目做过评价
    CommonUtils.assertsTrueWithMessage(
        companyScoreDetailService.countByUserAndProjectId(UserUtil.getUserId(),
            companyScore.getProjectId()) == 0, "您已评价过该项目,请不要重复评价");
    final Long comId = project.getComId();
    final CompanyScoreEntity companyScoreEntity = CommonUtils.requireNotNull(
        companyScoreService.getByIdCompanyId(comId),
        "项目公司数据有误,请联系管理员");
    transactionTemplate.executeWithoutResult(status -> {
      //获得公司信息
      final CompanyScoreDetailEntity detail = buildCompanyScoreDetailEntity(
          companyScore, companyScoreEntity.getId());
      companyScoreDetailService.save(detail);
      refreshCompanyScore(companyScoreEntity);
      messageBusiness.addMessage(MessageTemplateEnum.A18,
          messageBusiness.buildProjectProperties(project), String.valueOf(detail.getId()),
          project.getCreateBy(), companyService.getNameById(project.getComId()),
          UserUtil.getUserId());
    });

  }


  public void laborRateByDemander(LaborScore laborScore) {
    //校验权限
    final ProjectEntity project = getAndCheckProject(laborScore.getProjectId());
    final Long userId = UserUtil.getUserId();
    CommonUtils.assertsTrueWithMessage(userId.compareTo(project.getCreateBy()) == 0,
        "你是不该项目的项目创建人,不能评价");
    //
    checkLaborProject(laborScore);
    doLaborRate(laborScore, project, MessageTemplateEnum.A19_1);
  }

  private void doLaborRate(LaborScore laborScore, ProjectEntity project,
      MessageTemplateEnum messageTemplate) {
    final LaborScoreEntity laborScoreEntity = CommonUtils.requireNotNull(
        laborScoreService.getByLaborId(laborScore.getLaborId()), "数据有误,请联系管理员");
    //构建明细
    final LaborScoreDetailEntity laborScoreDetail = new LaborScoreDetailEntity()
        .setScoreId(laborScoreEntity.getId())
        .setProjectId(laborScore.getProjectId())
        .setProjectLaborId(laborScore.getLaborId())
        .setScore(laborScore.getScore())
        .setRemark(laborScore.getComment())
        .setCreateBy(UserUtil.getUserId())
        .setCreateTime(LocalDateTime.now())
        .setUpdateBy(UserUtil.getUserId())
        .setUpdateTime(LocalDateTime.now());
    transactionTemplate.executeWithoutResult(status -> {
      laborScoreDetailService.save(laborScoreDetail);
      refreshLaborScore(laborScoreEntity);
      messageBusiness.addMessage(messageTemplate,
          messageBusiness.buildProjectProperties(project), String.valueOf(laborScoreDetail.getId()),
          laborScore.getLaborId(), companyService.getNameById(project.getComId()),
          UserUtil.getUserId());
    });
  }

  private void refreshLaborScore(LaborScoreEntity laborScoreEntity) {
    //
    //计算平均分并取整
    final Integer avgScore = laborScoreDetailService.getAvgScore(laborScoreEntity.getId());
    laborScoreEntity.setAvgScore(avgScore)
        .setUpdateBy(UserUtil.getUserId())
        .setUpdateTime(LocalDateTime.now());
    laborScoreService.updateById(laborScoreEntity);
  }

  public void laborRateByTl(LaborScore laborScore) {
    final ProjectEntity project = getAndCheckProject(laborScore.getProjectId());
    final Long userId = UserUtil.getUserId();
    CommonUtils.assertsTrueWithMessage(userId.compareTo(project.getProjectLeader()) == 0,
        "你是不该项目的项目leader,不能评价");
    checkLaborProject(laborScore);
    doLaborRate(laborScore, project, MessageTemplateEnum.A19_1);
  }


  private ProjectEntity getAndCheckProject(String projectId) {
    final ProjectEntity project = CommonUtils.requireNotNull(
        projectService.getById(projectId), "项目ID不合法");
    if (!ProjectStatusEnum.couldRate(project.getStatus())) {
      throw new RuntimeException("项目未进入评价阶段,不允许评价");
    }
    return project;
  }

  private void checkLaborProject(LaborScore laborScore) {
    //校验labor与project关系
    CommonUtils.assertsTrueWithMessage(
        projectLaborService.countByLaborIdAndProjectId(laborScore.getLaborId(),
            laborScore.getProjectId()) > 0, "成员与项目关系不存在");
    //重复评价
    CommonUtils.assertsTrueWithMessage(
        laborScoreDetailService.countRated(laborScore.getLaborId(), laborScore.getProjectId(),
            UserUtil.getUserId()) == 0,
        "您已评价过该员工,请不要重复评价");
  }

  private void refreshCompanyScore(CompanyScoreEntity companyScoreEntity) {
    //计算平均分并取整
    final Integer avgScore = companyScoreDetailService.getAvgScore(companyScoreEntity.getId());
    companyScoreEntity.setAvgScore(avgScore)
        .setUpdateBy(UserUtil.getUserId())
        .setUpdateTime(LocalDateTime.now());
    companyScoreService.updateById(companyScoreEntity);

  }

  private CompanyScoreDetailEntity buildCompanyScoreDetailEntity(CompanyScore companyScore,
      Long scoreId) {
    final Long userId = UserUtil.getUserId();
    final LocalDateTime now = LocalDateTime.now();
    return new CompanyScoreDetailEntity().setScoreId(scoreId)
        .setProjectId(companyScore.getProjectId())
        .setProjectLaborId(userId)
        .setScore(companyScore.getScore())
        .setRemark(companyScore.getComment())
        .setCreateBy(userId)
        .setCreateTime(now)
        .setUpdateBy(userId)
        .setUpdateTime(now)
        ;
  }


  public Map<Long, LaborScoreEntity> getLaborScoreMapByLaborIds(List<Long> userIds) {
    return Optional.ofNullable(laborScoreService.listByLaborIds(userIds)).orElseGet(ArrayList::new)
        .stream()
        .collect(Collectors.toMap(LaborScoreEntity::getLaborId, v -> v, (v1, v2) -> v1));
  }

  public LaborScoreEntity getByLaborId(Long userId) {
    return laborScoreService.getByLaborId(userId);
  }
}
